package com.aliyun.dingtalk.service.impl;

import com.aliyun.dingtalk.config.AppConfig;
import com.aliyun.dingtalk.constant.UrlConstant;
import com.aliyun.dingtalk.exception.InvokeDingTalkException;
import com.aliyun.dingtalk.model.DeptWithUsers;
import com.aliyun.dingtalk.service.DingTalkUserService;
import com.aliyun.dingtalk.util.AccessTokenUtil;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.*;
import com.dingtalk.api.response.*;
import com.taobao.api.ApiException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.text.SimpleDateFormat;


/**
 * 用户管理
 */
@Slf4j
@Service
public class DingTalkUserServiceImpl implements DingTalkUserService {

    @Autowired
    private AppConfig appConfig;

    @Autowired
    private UserCacheServiceImpl userCacheService;


    @Override
    public Object getAllUsersWithDetailsFromCache() {
        return userCacheService.getCachedAllUsers();
    }

    public OapiV2UserGetResponse.UserGetResponse getUserInfo(String authCode) {

        // 1. 获取access_token
        String accessToken = AccessTokenUtil.getAccessToken(appConfig.getAppKey(), appConfig.getAppSecret());

        // 2. 获取用户ID
        String userId = getUserId(authCode, accessToken);

        // 2. 根据用户ID获取用户详情
        return getOapiV2UserGetResponseByUserId(userId, accessToken);

    }

    @Override
    public String getAccessToken() {
        String accessToken = AccessTokenUtil.getAccessToken(appConfig.getAppKey(), appConfig.getAppSecret());
        return accessToken;
    }


    @Override
    public Object getDeptList() {
        String accessToken = AccessTokenUtil.getAccessToken(appConfig.getAppKey(), appConfig.getAppSecret());
        // 创建钉钉客户端，使用获取子部门列表的URL
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");

        // 创建请求对象
        OapiV2DepartmentListsubRequest req = new OapiV2DepartmentListsubRequest();

        // 设置根部门ID为1（通常1是默认的根部门）
        req.setDeptId(1L);

        // 设置语言为中文
        req.setLanguage("zh_CN");

        try {
            // 执行请求并返回响应结果
            OapiV2DepartmentListsubResponse response = client.execute(req, accessToken);
            return response.getResult();
        } catch (ApiException e) {
            // 处理API调用异常
            e.printStackTrace();
            throw new InvokeDingTalkException(e.getErrCode(), e.getErrMsg());
        }
    }

    /**
     * 根据authCode获取用户ID
     *
     * @param authCode
     * @param accessToken
     * @return
     */
    private String getUserId(String authCode, String accessToken) {
        DingTalkClient client = new DefaultDingTalkClient(UrlConstant.GET_USER_INFO_URL);
        OapiV2UserGetuserinfoRequest req = new OapiV2UserGetuserinfoRequest();
        req.setCode(authCode);
        try {
            OapiV2UserGetuserinfoResponse oapiV2UserGetuserinfoResponse = client.execute(req, accessToken);
            if (oapiV2UserGetuserinfoResponse.isSuccess()) {
                OapiV2UserGetuserinfoResponse.UserGetByCodeResponse userGetByCodeResponse = oapiV2UserGetuserinfoResponse.getResult();
                return userGetByCodeResponse.getUserid();
            } else {
                throw new InvokeDingTalkException(oapiV2UserGetuserinfoResponse.getErrorCode(), oapiV2UserGetuserinfoResponse.getErrmsg());
            }

        } catch (ApiException e) {
            // 需要自己处理异常
            e.printStackTrace();
            throw new InvokeDingTalkException(e.getErrCode(), e.getErrMsg());
        }
    }

    /**
     * 根据用户ID获取用户详情
     *
     * @param userId
     * @param accessToken
     * @return
     */
    private OapiV2UserGetResponse.UserGetResponse getOapiV2UserGetResponseByUserId(String userId, String accessToken) {
        DingTalkClient client = new DefaultDingTalkClient(UrlConstant.USER_GET_URL);
        OapiV2UserGetRequest req = new OapiV2UserGetRequest();
        req.setUserid(userId);
        req.setLanguage("zh_CN");

        try {
            OapiV2UserGetResponse oapiV2UserGetResponse = client.execute(req, accessToken);
            if (oapiV2UserGetResponse.isSuccess()) {
                return oapiV2UserGetResponse.getResult();
            } else {
                throw new InvokeDingTalkException(oapiV2UserGetResponse.getErrorCode(), oapiV2UserGetResponse.getErrmsg());
            }

        } catch (ApiException e) {
            // 需要自己处理异常
            e.printStackTrace();
            throw new InvokeDingTalkException(e.getErrCode(), e.getErrMsg());
        }
    }



    @Override
    public Object getUserListByDeptId(Long deptId) {
        try {
            // 获取访问令牌
            String accessToken = getAccessToken();

            // 创建钉钉客户端
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/listid");

            // 创建请求对象
            OapiUserListidRequest request = new OapiUserListidRequest();
            request.setDeptId(deptId);

            // 执行请求
            OapiUserListidResponse response = client.execute(request, accessToken);

            // 返回结果
            return response.getResult();
        } catch (Exception e) {
            log.error("获取部门用户列表失败", e);
            throw new RuntimeException("获取部门用户列表失败: " + e.getMessage());
        }
    }


    @Override
    public Object getDeptListWithUsers() {
        try {
            String accessToken = getAccessToken();

            // 获取根部门下的所有一级子部门
            List<DeptWithUsers> rootDepts = fetchDeptWithUsers(1L, accessToken);

            return rootDepts;
        } catch (Exception e) {
            log.error("获取部门及用户列表失败", e);
            throw new RuntimeException("获取部门及用户列表失败: " + e.getMessage());
        }
    }



    @Override
    public Object getAllUsersWithDetails() {
        try {
            String accessToken = getAccessToken();

            // 获取根部门下的所有子部门和用户信息
            List<DeptWithUsers> allDeptsWithUsers = fetchDeptWithUsers(1L, accessToken);

            // 构建简化格式的用户列表
            List<Map<String, Object>> simplifiedUserList = new ArrayList<>();

            // 遍历所有部门和用户，构建简化格式
            for (DeptWithUsers dept : allDeptsWithUsers) {
                // 遍历部门下的每个用户
                if (dept.getUserListWithDetails() != null) {
                    for (Map<String, Object> userWithDetails : dept.getUserListWithDetails()) {
                        Map<String, Object> simplifiedUser = new HashMap<>();
                        simplifiedUser.put("userId", userWithDetails.get("userId"));
                        simplifiedUser.put("details", userWithDetails.get("details"));
                        simplifiedUser.put("departmentName", dept.getName());
                        simplifiedUserList.add(simplifiedUser);
                    }
                }

                // 递归处理子部门
                addUsersFromChildDepts(dept.getChildDepts(), simplifiedUserList);
            }

            Map<String, Object> result = new HashMap<>();
            result.put("userListWithDetails", simplifiedUserList);
            return result;
        } catch (Exception e) {
            log.error("获取所有用户详细信息失败", e);
            throw new RuntimeException("获取所有用户详细信息失败: " + e.getMessage());
        }
    }

    /**
     * 递归添加子部门中的用户到简化列表
     *
     * @param childDepts 子部门列表
     * @param simplifiedUserList 简化用户列表
     */
    private void addUsersFromChildDepts(List<DeptWithUsers> childDepts, List<Map<String, Object>> simplifiedUserList) {
        if (childDepts != null) {
            for (DeptWithUsers childDept : childDepts) {
                // 遍历子部门下的每个用户
                if (childDept.getUserListWithDetails() != null) {
                    for (Map<String, Object> userWithDetails : childDept.getUserListWithDetails()) {
                        Map<String, Object> simplifiedUser = new HashMap<>();
                        simplifiedUser.put("userId", userWithDetails.get("userId"));
                        simplifiedUser.put("details", userWithDetails.get("details"));
                        simplifiedUser.put("departmentName", childDept.getName());
                        simplifiedUserList.add(simplifiedUser);
                    }
                }

                // 递归处理更深层的子部门
                addUsersFromChildDepts(childDept.getChildDepts(), simplifiedUserList);
            }
        }
    }




    /**
     * 根据部门ID获取部门名称
     *
     * @param deptId 部门ID
     * @param accessToken 访问令牌
     * @return 部门名称
     */
    private String getDepartmentName(Long deptId, String accessToken) {
        try {
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/get");
            OapiV2DepartmentGetRequest req = new OapiV2DepartmentGetRequest();
            req.setDeptId(deptId);
            req.setLanguage("zh_CN");
            OapiV2DepartmentGetResponse response = client.execute(req, accessToken);

            if (response.isSuccess() && response.getResult() != null) {
                return response.getResult().getName();
            }
        } catch (ApiException e) {
            log.error("获取部门{}名称失败", deptId, e);
        }
        return "";
    }

    /**
     * 递归收集所有部门下的用户ID
     *
     * @param deptId 部门ID
     * @param accessToken 访问令牌
     * @param userIdSet 用户ID集合
     * @throws ApiException API异常
     */
    private void collectAllUserIds(Long deptId, String accessToken, Set<String> userIdSet) throws ApiException {
        // 获取当前部门下的用户列表
        DingTalkClient userClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/listid");
        OapiUserListidRequest userReq = new OapiUserListidRequest();
        userReq.setDeptId(deptId);
        OapiUserListidResponse userResponse = userClient.execute(userReq, accessToken);

        if (userResponse.isSuccess() && userResponse.getResult() != null &&
                userResponse.getResult().getUseridList() != null) {
            userIdSet.addAll(userResponse.getResult().getUseridList());
        }

        // 获取当前部门的子部门列表
        DingTalkClient deptClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
        OapiV2DepartmentListsubRequest deptReq = new OapiV2DepartmentListsubRequest();
        deptReq.setDeptId(deptId);
        deptReq.setLanguage("zh_CN");

        OapiV2DepartmentListsubResponse deptResponse = deptClient.execute(deptReq, accessToken);

        if (deptResponse.isSuccess() && deptResponse.getResult() != null) {
            // 递归处理每个子部门
            for (OapiV2DepartmentListsubResponse.DeptBaseResponse dept : deptResponse.getResult()) {
                collectAllUserIds(dept.getDeptId(), accessToken, userIdSet);
            }
        }
    }



    /**
     * 递归获取指定部门ID下的所有子部门和用户信息
     *
     * @param parentDeptId 父部门ID
     * @param accessToken 访问令牌
     * @return 包含子部门和用户信息的列表
     */
    private List<DeptWithUsers> fetchDeptWithUsers(Long parentDeptId, String accessToken) throws ApiException {
        List<DeptWithUsers> result = new ArrayList<>();

        // 获取当前层级的所有子部门
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsub");
        OapiV2DepartmentListsubRequest req = new OapiV2DepartmentListsubRequest();
        req.setDeptId(parentDeptId);
        req.setLanguage("zh_CN");

        OapiV2DepartmentListsubResponse response = client.execute(req, accessToken);

        if (response.isSuccess() && response.getResult() != null) {
            for (OapiV2DepartmentListsubResponse.DeptBaseResponse dept : response.getResult()) {
                DeptWithUsers deptWithUsers = new DeptWithUsers();
                deptWithUsers.setDeptId(dept.getDeptId());
                deptWithUsers.setName(dept.getName());
                deptWithUsers.setParentId(dept.getParentId());
                deptWithUsers.setAutoAddUser(dept.getAutoAddUser());
                deptWithUsers.setCreateDeptGroup(dept.getCreateDeptGroup());
                deptWithUsers.setExt(dept.getExt());

                // 获取该部门下的用户列表
                List<Map<String, Object>> userListWithDetails = new ArrayList<>();
                try {
                    DingTalkClient userClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/user/listid");
                    OapiUserListidRequest userReq = new OapiUserListidRequest();
                    userReq.setDeptId(dept.getDeptId());
                    OapiUserListidResponse userResponse = userClient.execute(userReq, accessToken);

                    if (userResponse.isSuccess() && userResponse.getResult() != null) {
                        List<String> userIdList = userResponse.getResult().getUseridList();
                        deptWithUsers.setUseridList(userIdList);

                        // 获取每个用户的详细信息
                        for (String userId : userIdList) {
                            try {
                                DingTalkClient userDetailsClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
                                OapiV2UserGetRequest userDetailsReq = new OapiV2UserGetRequest();
                                userDetailsReq.setUserid(userId);
                                userDetailsReq.setLanguage("zh_CN");
                                OapiV2UserGetResponse userDetailsResponse = userDetailsClient.execute(userDetailsReq, accessToken);

                                Map<String, Object> userWithDetails = new HashMap<>();
                                userWithDetails.put("userId", userId);

                                if (userDetailsResponse.isSuccess() && userDetailsResponse.getResult() != null) {
                                    userWithDetails.put("details", userDetailsResponse.getResult());
                                } else {
                                    userWithDetails.put("details", null);
                                }

                                userListWithDetails.add(userWithDetails);
                            } catch (ApiException e) {
                                log.error("获取用户{}的详细信息失败", userId, e);
                                // 即使获取详细信息失败，也要保留用户ID
                                Map<String, Object> userWithDetails = new HashMap<>();
                                userWithDetails.put("userId", userId);
                                userWithDetails.put("details", null);
                                userListWithDetails.add(userWithDetails);
                            }
                        }
                    } else {
                        deptWithUsers.setUseridList(new ArrayList<>());
                    }
                } catch (ApiException e) {
                    log.error("获取部门{}的用户列表失败", dept.getDeptId(), e);
                    deptWithUsers.setUseridList(new ArrayList<>());
                }

                // 设置包含详细信息的用户列表
                deptWithUsers.setUserListWithDetails(userListWithDetails);

                // 如果是顶级部门的直接子部门，则获取其子部门列表
                if (Objects.equals(dept.getParentId(), 1L)) {
                    try {
                        DingTalkClient subDeptClient = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/department/listsubid");
                        OapiV2DepartmentListsubidRequest subDeptReq = new OapiV2DepartmentListsubidRequest();
                        subDeptReq.setDeptId(dept.getDeptId());
                        OapiV2DepartmentListsubidResponse subDeptResponse = subDeptClient.execute(subDeptReq, accessToken);

//                        if (subDeptResponse.isSuccess() && subDeptResponse.getResult() != null) {
//                            deptWithUsers.setSubDeptIdList(subDeptResponse.getResult().getDeptIdList());
//                        } else {
//                            deptWithUsers.setSubDeptIdList(new ArrayList<>());
//                        }
                    } catch (ApiException e) {
                        log.error("获取部门{}的子部门列表失败", dept.getDeptId(), e);
//                        deptWithUsers.setSubDeptIdList(new ArrayList<>());
                    }
                }

                // 递归获取子部门的信息（包括它们的用户）
                List<DeptWithUsers> childDepts = fetchDeptWithUsers(dept.getDeptId(), accessToken);
                deptWithUsers.setChildDepts(childDepts); // 假设DeptWithUsers中有childDepts字段

                result.add(deptWithUsers);
            }
        }

        return result;
    }






    // 在 DingTalkUserServiceImpl 类中添加以下实现
    @Override
    public Object getUserDetail(String userId) {
        try {
            // 获取访问令牌
            String accessToken = getAccessToken();

            // 创建钉钉客户端
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");

            // 创建请求对象
            OapiV2UserGetRequest request = new OapiV2UserGetRequest();
            request.setUserid(userId);
            request.setLanguage("zh_CN");

            // 执行请求
            OapiV2UserGetResponse response = client.execute(request, accessToken);

            // 返回结果
            if (response.isSuccess()) {
                return response.getResult();
            } else {
                throw new RuntimeException("获取用户详情失败: " + response.getErrmsg());
            }
        } catch (Exception e) {
            log.error("获取用户详情失败", e);
            throw new RuntimeException("获取用户详情失败: " + e.getMessage());
        }
    }


    @Override
    public Object getAttendanceList(List<String> userIdList, String startDate, String endDate, Long offset, Long limit) {
        try {
            // 获取访问令牌
            String accessToken = getAccessToken();

            // 创建钉钉客户端
            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/attendance/list");

            // 创建请求对象
            OapiAttendanceListRequest request = new OapiAttendanceListRequest();
            request.setWorkDateFrom(startDate);
            request.setWorkDateTo(endDate);
            request.setUserIdList(userIdList);
            request.setOffset(offset);
            request.setLimit(limit);
            request.setIsI18n(false);

            // 执行请求
            OapiAttendanceListResponse response = client.execute(request, accessToken);

            // 返回结果
            if (response.isSuccess()) {
                // 按日期和用户ID分组的记录
                Map<String, Map<String, Object>> dateUserGroupedRecords = new LinkedHashMap<>();

                // 解析查询日期范围
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date queryStartDate = dateFormat.parse(startDate);
                Date queryEndDate = dateFormat.parse(endDate);

                // 扩大查询范围，包含第二天凌晨5点前的记录
                Calendar extendedEndCal = Calendar.getInstance();
                extendedEndCal.setTime(queryEndDate);
                extendedEndCal.add(Calendar.DAY_OF_MONTH, 1);
                extendedEndCal.set(Calendar.HOUR_OF_DAY, 5);
                extendedEndCal.set(Calendar.MINUTE, 0);
                extendedEndCal.set(Calendar.SECOND, 0);
                Date extendedEndDate = extendedEndCal.getTime();

                // 按日期和用户分组记录
                for (OapiAttendanceListResponse.Recordresult record : response.getRecordresult()) {
                    // 获取打卡时间
                    Date userCheckTime = record.getUserCheckTime();

                    // 检查打卡时间是否在扩展查询范围内
                    if (userCheckTime.before(queryStartDate) || userCheckTime.after(extendedEndDate)) {
                        continue; // 跳过不在扩展查询范围内的记录
                    }

                    // 确定记录应该归属的日期
                    String workDateStr = determineRecordDateForQuery(record, queryStartDate, queryEndDate);

                    // 如果归属日期不在查询范围内，则跳过
                    if (workDateStr == null) {
                        continue;
                    }

                    String userId = record.getUserId();
                    // 使用日期和用户ID组合作为键
                    String dateUserKey = workDateStr + "_" + userId;

                    // 初始化该日期+用户的数据结构
                    if (!dateUserGroupedRecords.containsKey(dateUserKey)) {
                        Map<String, Object> dateUserEntry = new LinkedHashMap<>();
                        dateUserEntry.put("date", workDateStr);
                        dateUserEntry.put("userId", userId);
                        dateUserEntry.put("records", new ArrayList<Map<String, Object>>());
                        dateUserEntry.put("firstCheckTime", ""); // 上班打卡时间
                        dateUserEntry.put("lastCheckTime", "");  // 下班打卡时间
                        dateUserGroupedRecords.put(dateUserKey, dateUserEntry);
                    }

                    // 构建单条记录
                    Map<String, Object> formattedRecord = buildFormattedRecord(record);

                    // 添加到对应日期+用户的记录列表中
                    ((List<Map<String, Object>>) dateUserGroupedRecords.get(dateUserKey).get("records")).add(formattedRecord);
                }

                // 对每组记录进行后处理，筛选出每人每天最多两条记录（最早上班+最晚下班）
                for (Map<String, Object> dateUserEntry : dateUserGroupedRecords.values()) {
                    List<Map<String, Object>> records = (List<Map<String, Object>>) dateUserEntry.get("records");

                    // 按时间排序记录
                    records.sort((r1, r2) -> {
                        String time1 = (String) r1.get("userCheckTime");
                        String time2 = (String) r2.get("userCheckTime");
                        return time1.compareTo(time2);
                    });

                    // 根据时间重新确定打卡类型
                    assignCheckTypes(records);

                    // 筛选出每人每天最多两条记录：最早上班 + 最晚下班
                    Map<String, Object> earliestOnDuty = null;  // 最早上班卡
                    Map<String, Object> latestOffDuty = null;   // 最晚下班卡

                    for (Map<String, Object> record : records) {
                        String checkType = (String) record.get("checkType");
                        String userCheckTime = (String) record.get("userCheckTime");

                        if ("上班".equals(checkType)) {
                            // 选择最早的上班打卡记录
                            if (earliestOnDuty == null ||
                                    userCheckTime.compareTo((String) earliestOnDuty.get("userCheckTime")) < 0) {
                                earliestOnDuty = record;
                            }
                        } else if ("下班".equals(checkType)) {
                            // 选择最晚的下班打卡记录
                            if (latestOffDuty == null ||
                                    userCheckTime.compareTo((String) latestOffDuty.get("userCheckTime")) > 0) {
                                latestOffDuty = record;
                            }
                        }
                    }

                    // 构建新的记录列表，最多包含两条记录
                    List<Map<String, Object>> filteredRecords = new ArrayList<>();
                    if (earliestOnDuty != null) {
                        filteredRecords.add(earliestOnDuty);
                    }
                    if (latestOffDuty != null) {
                        filteredRecords.add(latestOffDuty);
                    }

                    // 按时间排序最终记录
                    filteredRecords.sort((r1, r2) -> {
                        String time1 = (String) r1.get("userCheckTime");
                        String time2 = (String) r2.get("userCheckTime");
                        return time1.compareTo(time2);
                    });

                    // 更新记录列表
                    dateUserEntry.put("records", filteredRecords);

                    // 更新 firstCheckTime 和 lastCheckTime
                    String firstCheckTime = "";
                    String lastCheckTime = "";

                    for (Map<String, Object> record : filteredRecords) {
                        String checkType = (String) record.get("checkType");
                        String userCheckTime = (String) record.get("userCheckTime");

                        if ("上班".equals(checkType)) {
                            if ("".equals(firstCheckTime) || userCheckTime.compareTo(firstCheckTime) < 0) {
                                firstCheckTime = userCheckTime;
                            }
                        } else if ("下班".equals(checkType)) {
                            if ("".equals(lastCheckTime) || userCheckTime.compareTo(lastCheckTime) > 0) {
                                lastCheckTime = userCheckTime;
                            }
                        }
                    }

                    dateUserEntry.put("firstCheckTime", firstCheckTime);
                    dateUserEntry.put("lastCheckTime", lastCheckTime);
                }

                // 转换为列表形式并排序
                List<Map<String, Object>> result = new ArrayList<>(dateUserGroupedRecords.values());

                // 按日期和用户ID排序
                result.sort((r1, r2) -> {
                    String date1 = (String) r1.get("date");
                    String date2 = (String) r2.get("date");
                    int dateCompare = date1.compareTo(date2);
                    if (dateCompare != 0) {
                        return dateCompare;
                    }
                    // 如果日期相同，按用户ID排序
                    String userId1 = (String) r1.get("userId");
                    String userId2 = (String) r2.get("userId");
                    return userId1.compareTo(userId2);
                });

                return result;
            } else {
                throw new RuntimeException("获取考勤记录失败: " + response.getErrmsg());
            }
        } catch (Exception e) {
            log.error("获取考勤记录失败", e);
            throw new RuntimeException("获取考勤记录失败: " + e.getMessage());
        }
    }




    /**
     * 确定打卡记录应该归属的日期（针对查询范围）
     *
     * @param record 原始打卡记录
     * @param queryStartDate 查询开始时间
     * @param queryEndDate 查询结束时间
     * @return 归属日期字符串 (yyyy-MM-dd)，如果不在查询范围内则返回null
     */
    private String determineRecordDateForQuery(OapiAttendanceListResponse.Recordresult record, Date queryStartDate, Date queryEndDate) {
        Date userCheckTime = record.getUserCheckTime();
        Calendar checkTimeCal = Calendar.getInstance();
        checkTimeCal.setTime(userCheckTime);

        // 判断是否在凌晨5点之前打卡
        Calendar thresholdCal = Calendar.getInstance();
        thresholdCal.setTime(userCheckTime);
        thresholdCal.set(Calendar.HOUR_OF_DAY, 5);
        thresholdCal.set(Calendar.MINUTE, 0);
        thresholdCal.set(Calendar.SECOND, 0);
        thresholdCal.set(Calendar.MILLISECOND, 0);

        Calendar workDateCal = Calendar.getInstance();
        workDateCal.setTime(userCheckTime);

        if (checkTimeCal.before(thresholdCal)) {
            // 如果在凌晨5点之前打卡，视为前一天的下班卡
            workDateCal.add(Calendar.DAY_OF_MONTH, -1);
        }
        // 否则视为当天的上班卡或下班卡

        // 检查归属日期是否在查询范围内
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String workDateStr = sdf.format(workDateCal.getTime());

        try {
            Date workDate = sdf.parse(workDateStr);
            if (!workDate.before(queryStartDate) && !workDate.after(queryEndDate)) {
                return workDateStr;
            }
        } catch (Exception e) {
            log.warn("解析归属日期失败: {}", workDateStr, e);
        }

        return null; // 不在查询范围内
    }


    /**
     * 根据时间规则分配打卡类型
     * 凌晨5点前的打卡记录视为前一天的下班卡
     * 凌晨5点后的第一条打卡记录视为当天的上班卡
     *
     * @param records 同一天同一用户的打卡记录列表（已按时间排序）
     */
    private void assignCheckTypes(List<Map<String, Object>> records) {
        if (records.isEmpty()) {
            return;
        }

        boolean hasOnDutyAssigned = false;

        for (int i = 0; i < records.size(); i++) {
            Map<String, Object> record = records.get(i);
            String userCheckTimeStr = (String) record.get("userCheckTime");

            try {
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                Date checkTime = sdf.parse(userCheckTimeStr);
                Calendar cal = Calendar.getInstance();
                cal.setTime(checkTime);

                // 判断是否在凌晨5点前
                if (cal.get(Calendar.HOUR_OF_DAY) < 5) {
                    // 凌晨5点前的打卡记录视为下班卡
                    record.put("checkType", "下班");
                } else {
                    // 凌晨5点后的打卡记录处理
                    if (!hasOnDutyAssigned) {
                        // 第一条视为上班卡
                        record.put("checkType", "上班");
                        hasOnDutyAssigned = true;
                    } else {
                        // 其余的暂时标记为下班卡（后续可能会调整）
                        record.put("checkType", "下班");
                    }
                }
            } catch (Exception e) {
                log.warn("解析打卡时间失败: {}", userCheckTimeStr, e);
            }
        }
    }



    /**
     * 构建格式化的考勤记录
     *
     * @param record 原始考勤记录
     * @return 格式化后的记录
     */
    private Map<String, Object> buildFormattedRecord(OapiAttendanceListResponse.Recordresult record) {
        Map<String, Object> formattedRecord = new HashMap<>();

        // 格式化考勤类型
        String checkType = "";
        if ("OnDuty".equals(record.getCheckType())) {
            checkType = "上班";
        } else if ("OffDuty".equals(record.getCheckType())) {
            checkType = "下班";
        } else {
            checkType = record.getCheckType();
        }

        // 格式化打卡结果
        String timeResult = "";
        if ("Normal".equals(record.getTimeResult())) {
            timeResult = "正常";
        } else if ("Late".equals(record.getTimeResult())) {
            timeResult = "迟到";
        } else if ("Early".equals(record.getTimeResult())) {
            timeResult = "早退";
        } else if ("SeriousLate".equals(record.getTimeResult())) {
            timeResult = "严重迟到";
        } else if ("Absenteeism".equals(record.getTimeResult())) {
            timeResult = "旷工迟到";
        } else if ("NotSigned".equals(record.getTimeResult())) {
            timeResult = "未打卡";
        } else {
            timeResult = record.getTimeResult();
        }

        // 格式化数据来源
        String sourceType = "";
        if ("USER".equals(record.getSourceType())) {
            sourceType = "用户打卡";
        } else if ("ATM".equals(record.getSourceType())) {
            sourceType = "考勤机打卡";
        } else if ("APPROVE".equals(record.getSourceType())) {
            sourceType = "审批系统";
        } else if ("BOSS".equals(record.getSourceType())) {
            sourceType = "老板改签";
        } else if ("SYSTEM".equals(record.getSourceType())) {
            sourceType = "考勤系统";
        } else if ("AUTO_CHECK".equals(record.getSourceType())) {
            sourceType = "自动打卡";
        } else if ("DING_ATM".equals(record.getSourceType())) {
            sourceType = "钉钉考勤机";
        } else if ("BEACON".equals(record.getSourceType())) {
            sourceType = "IBeacon";
        } else {
            sourceType = record.getSourceType();
        }

        // 格式化位置结果
        String locationResult = "";
        if ("Normal".equals(record.getLocationResult())) {
            locationResult = "范围内";
        } else if ("Outside".equals(record.getLocationResult())) {
            locationResult = "范围外";
        } else if ("NotSigned".equals(record.getLocationResult())) {
            locationResult = "未打卡";
        } else {
            locationResult = record.getLocationResult();
        }

        // 时间格式化器
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));

        // 设置格式化后的字段
        formattedRecord.put("checkType", checkType);
        formattedRecord.put("timeResult", timeResult);
        formattedRecord.put("sourceType", sourceType);
        formattedRecord.put("locationResult", locationResult);

        if (record.getBaseCheckTime() != null) {
            formattedRecord.put("baseCheckTime", sdf.format(record.getBaseCheckTime()));
        } else {
            formattedRecord.put("baseCheckTime", "");
        }

        if (record.getUserCheckTime() != null) {
            formattedRecord.put("userCheckTime", sdf.format(record.getUserCheckTime()));
        } else {
            formattedRecord.put("userCheckTime", "");
        }

        formattedRecord.put("userId", record.getUserId());
        formattedRecord.put("recordId", record.getRecordId());
        formattedRecord.put("planId", record.getPlanId());
        formattedRecord.put("groupId", record.getGroupId());
        formattedRecord.put("id", record.getId());

        // 可选字段
        if (record.getProcInstId() != null) {
            formattedRecord.put("procInstId", record.getProcInstId());
        }
        if (record.getApproveId() != null) {
            formattedRecord.put("approveId", record.getApproveId());
        }

        return formattedRecord;
    }








}
